/*!
    \copyright  Copyright (c) 2023 - 2024 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \addtogroup le_unicast_manager
    \brief      Data for a GATT connection being tracked by the le unicast manager
    @{
*/
#ifndef LE_UNICAST_MANAGER_INSTANCE_H
#define LE_UNICAST_MANAGER_INSTANCE_H

#include "le_unicast_manager_private.h"

void LeUnicastManager_InstanceInit(void);

/*! \brief Reset Unicast manager instance. */
void LeUnicastManager_InstanceReset(le_um_instance_t *inst);

/*! \brief Get the default unicast manager instance.

    Get the 'default' unicast instance that code before the LE Audio multipoint
    changes expected.

    \note This is here for backwards compatibility only. Eventually all the
          le_unicast_manager code will be refactored to get the instance by
          an identifier (cid, voice_source, etc.). When that happens this
          function will be removed.

    \return The default unicast manager instance.
*/
le_um_instance_t* LeUnicastManager_GetInstanceByFocus(void);

/*! \brief Get the unicast manager instance based on the GATT connection Id.

    \param cid GATT connection id to get the unicast manager insrance for.

    \return Pointer to the a unicast manager instance or NULL if there was no match.
*/
le_um_instance_t* LeUnicastManager_InstanceGetByCid(gatt_cid_t cid);

/*! \brief Get the unicast manager instance based on the voice source.

    \param source Voice source to get the unicast manager instance for.

    \return Pointer to the a unicast manager instance or NULL if there was no match.
*/
le_um_instance_t* LeUnicastManager_InstanceGetByVoiceSource(voice_source_t source);

/*! \brief Get the unicast manager instance based on the audio source.

    \param source Audio source to get the unicast manager instance for.

    \return Pointer to the a unicast manager instance or NULL if there was no match.
*/
le_um_instance_t* LeUnicastManager_InstanceGetByAudioSource(audio_source_t source);

/*! \brief Get the unicast manager instance based on generic source

    \param source Generic source to get the unicast manager instance for.

    \return Pointer to the a unicast manager instance or NULL if there was no match.
*/
le_um_instance_t* LeUnicastManager_InstanceGetByGenericSource(generic_source_t source);

/*! \brief Get the unicast manager instance as well as CIS data based on the CIS handle.

    \param cis_handle CIS handle to get the unicast manager instance for.
    \param retrieved_cis Double pointer to return CIS data pointer (Ignored if NULL.

    \return Pointer to the a unicast manager instance or NULL if there was no match.
*/
le_um_instance_t* LeUnicastManager_InstanceAndCisDataGetByCisHandle(uint16 cis_handle, le_um_cis_t **retrieved_cis);

/*! \brief Get the unicast manager instance based on the CIS handle.

    \param cis_handle CIS handle to get the unicast manager instance for.

    \return Pointer to the a unicast manager instance or NULL if there was no match.
*/
le_um_instance_t* LeUnicastManager_InstanceGetByCisHandle(uint16 cis_handle);

/*! \brief Get the unicast manager instance based on the CIS id in the ASE QoS config data.

    Note: this is used when matching a newly created CIS with an ASE and instance.

    \param cis_id CIS id to get the unicast manager instance for.

    \return Pointer to the a unicast manager instance or NULL if there was no match.
*/
le_um_instance_t* LeUnicastManager_InstanceGetByAseCisId(uint8 cis_id);

/*! \brief Get or create a new instance for a GATT connection.

    This function will first try to find an existing instance based on the GATT
    connection Id. If none is found then it will attempt to create a new
    instance.

    \param cid GATT connection Id for the new instance.

    \return A pointer to the new instance; NULL if unable to create one.
*/
le_um_instance_t* LeUnicastManager_InstanceGetByCidOrCreate(gatt_cid_t cid);

/*! \brief Get the audio source from the device property, associated with the instance

    \param inst Instance for which the audio source is required.

    \return audio source associated with the instance
*/
audio_source_t LeUnicastManager_GetAudioSourceForInstance(le_um_instance_t *inst);

/*! \brief Destroy's the instance for a GATT connection.

    This function will additionallty remove the allocated audio & voice sources maintained
    by this instance.

    \param inst Unicast manager instance that needs to be destroyed.
*/
void LeUnicastManager_DestroyInstance(le_um_instance_t *inst);

/*! \brief Get the other instance other than provided instance

    \param le_um_instance_t the instance which is not required

    \return The other instance
*/
le_um_instance_t* LeUnicastManager_GetOtherInstance(le_um_instance_t *this_inst);

/*! \brief Get the count of unicast manager instances which are not in idle state

    \return Number of unicast manager instances which are not in idle state
*/
uint8_t LeUnicastManager_GetNonIdleInstanceCount(void);

/*! \brief Get the voice source from the device property, associated with the instance

    \param inst Instance for which the voice source is required.

    \return voice source associated with the instance
*/
voice_source_t LeUnicastManager_GetVoiceSourceForInstance(le_um_instance_t *inst);

/*! Get Cis Link loss message for the instance

    \param inst instance for which the Cis Linkloss Message is requested

    \return Cis link loss Message for instance
*/
le_um_internal_msg_t LeUnicastManager_GetCisLinklossMessageForInst(le_um_instance_t *inst);

/*! Get the instance by BT Address

    \param addr public address using which the instance will be retrieved

    \return Instance
*/
le_um_instance_t* LeUnicastManager_GetInstanceByBdaddr(bdaddr *addr);

/*! \brief Gets the generic source associated with the instance

    \param inst       The unicast manager instance for which the source is required
    \param source     Pointer to generic source.
*/
void leUnicastManager_GetGenericSourceForInstance(le_um_instance_t *inst, generic_source_t *source);

/*! \brief Update the instance-wide audio context
    \param inst The Unicast instance to be updated
    \param audio_context The Audio Context for the instance
*/
void LeUnicastManager_UpdateInstanceAudioContext(le_um_instance_t *inst, uint16 audio_context);


/*! Checks if a instance is valid. Currently that means it has a valid GATT connection_id. */
#define LeUnicastManager_InstanceIsValid(inst)      (INVALID_CID != (inst)->cid)

/*! Returns the current active unicast audio instance */
#define LeUnicastManager_InstanceGetAudioContext(inst)    ((inst)->audio_context)

/*! Returns the Left Sink ASE */
#define LeUnicastManager_InstanceGetLeftSinkAse(inst)     (&(inst)->ase[le_um_audio_location_left_sink])

/*! Returns the Right Sink ASE */
#define LeUnicastManager_InstanceGetRightSinkAse(inst)    (&(inst)->ase[le_um_audio_location_right_sink])

/*! Returns the Left Source ASE */
#define LeUnicastManager_InstanceGetLeftSourceAse(inst)   (&(inst)->ase[le_um_audio_location_left_source])

/*! Returns the Right Source ASE */
#define LeUnicastManager_InstanceGetRightSourceAse(inst)  (&(inst)->ase[le_um_audio_location_right_source])

/*! Gets instance based on focus */
#define LeUnicastManager_GetInstance()                    (LeUnicastManager_GetInstanceByFocus())

#ifdef INCLUDE_MIRRORING
/*! \brief Checks if the cis relay is supported for this LE instance.

    \param inst      LE Audio instance.

    \return TRUE, if cis relay is supported FALSE otherwise.
*/
#define leUnicastManager_IsRelayedEnabledForInst(inst) \
            LeUnicastManager_IsRelayEnabled((inst)->mirror_type, \
                                            (inst)->audio_context, \
                                            LeUnicastManager_GetLeAudioCodec(inst))

/*! \brief Check if rendering single cis and relay is required for the ongoing usecase.

    \param inst      LE Audio instance.

    \return TRUE, if single cis relay is enabled, FALSE otherwise.
*/
#define leUnicastManager_IsSingleCisRelayEnabledForInst(inst) \
            LeUnicastManager_IsSingleCisRelayEnabled((inst)->mirror_type, \
                                                     (inst)->audio_context, \
                                                     LeUnicastManager_GetLeAudioCodec(inst))

/*! \brief Check if rendering dual cis and relay is required for the ongoing usecase.

    \param inst      LE Audio instance.

    \return TRUE, if dual cis relay is enabled, FALSE otherwise.
*/
#define leUnicastManager_IsDualCisRelayEnabledForInst(inst) \
            LeUnicastManager_IsDualCisRelayEnabled((inst)->mirror_type, \
                                                   (inst)->audio_context, \
                                                   LeUnicastManager_GetLeAudioCodec(inst))
#else /* INCLUDE_MIRRORING */

#define leUnicastManager_IsSingleCisRelayEnabledForInst(inst)      (FALSE)
#define leUnicastManager_IsDualCisRelayEnabledForInst(inst)        (FALSE)
#define leUnicastManager_IsRelayedEnabledForInst(inst)             (FALSE)

#endif /* INCLUDE_MIRRORING */

#endif // LE_UNICAST_MANAGER_INSTANCE_H
/*! @} */
